package org.jeecg.modules.core.highway.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.core.base.entity.BaseCar;
import org.jeecg.modules.core.base.entity.BaseCarWeightLimit;
import org.jeecg.modules.core.base.mapper.BaseCarMapper;
import org.jeecg.modules.core.base.mapper.BaseCarWeightLimitMapper;
import org.jeecg.modules.core.base.service.IBaseCarService;
import org.jeecg.modules.core.highway.entity.DataOverloadHighway;
import org.jeecg.modules.core.highway.entity.PassDataHighway;
import org.jeecg.modules.core.highway.entity.PassDataHighwayPic;
import org.jeecg.modules.core.highway.mapper.DataOverloadHighwayMapper;
import org.jeecg.modules.core.highway.mapper.PassDataHighwayMapper;
import org.jeecg.modules.core.highway.mapper.PassDataHighwayPicMapper;
import org.jeecg.modules.core.highway.service.IPassDataHighwayService;
import org.jeecg.modules.core.highway.vo.PassDataHighwayPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 公路站点过磅数据表
 * @Author: jeecg-boot
 * @Date: 2021-07-21
 * @Version: V1.0
 */
@Service
public class PassDataHighwayServiceImpl extends ServiceImpl<PassDataHighwayMapper, PassDataHighway> implements IPassDataHighwayService {

    @Resource
    private PassDataHighwayMapper passDataHighwayMapper;
    @Resource
    private PassDataHighwayPicMapper passDataHighwayPicMapper;

    @Resource
    DataOverloadHighwayMapper dataOverloadHighwayMapper;

    @Autowired
    private IBaseCarService baseCarService;

    @Resource
    BaseCarWeightLimitMapper baseCarWeightLimitMapper;

    @Resource
    BaseCarMapper baseCarMapper;

    @Autowired
    public RedisTemplate<String, Object> redisTemplate;

    @Override
    @Transactional
    public void saveMain(PassDataHighway passDataHighway, List<PassDataHighwayPic> passDataHighwayPicList) throws Exception {
        //车辆表相关业务逻辑操作
        vehicleOperating(passDataHighway);
        double weightLimit = passDataHighway.getWeightLimit();
        passDataHighway.setQueryTime(DateUtils.getIntYearMonthDay(passDataHighway.getCheckTime()));
        //如超载按检测类型分情况处理
        if ("0101".equals(passDataHighway.getCheckType()) && weightLimit * 1.05 < passDataHighway.getTotal()) {
            //固定站：初检	0101  初检的话超载表新增 过磅超载数据 超载表其他列赋值
            DataOverloadHighway dataOverload = overloadAssignment(passDataHighway);
            dataOverloadHighwayMapper.insert(dataOverload);
        } else if ("0202".equals(passDataHighway.getCheckType())) {
            //固定站：复检	0202  复检：车牌号查限定时间之内的过车数据
            List<DataOverloadHighway> before = getOverloadDate(passDataHighway.getVehicleNo());
            before.forEach(vo -> {
                //修改此条过车数据状态 是否结束 是否显示
                vo.setOvere(1);
                vo.setDisplay(0);
                if (weightLimit > passDataHighway.getTotal()) {
                    //超载表新增复检记录
                    vo.setOverloadState("未超载");
                }
                dataOverloadHighwayMapper.updateById(vo);
            });
            if (weightLimit < passDataHighway.getTotal()) {
                //超载表新增复检记录
                dataOverloadHighwayMapper.insert(overloadAssignment(passDataHighway));
            }
        } else if ("03".equals(passDataHighway.getCheckType())) {
            //非现场	03 暂不考虑
        } else if ("04".equals(passDataHighway.getCheckType())) {
            //入口劝返站	04 暂不考虑
        } else if ("05".equals(passDataHighway.getCheckType())) {
            //源头站	05 暂不考虑
        } else {
            //其他情况 暂不考虑
        }

        passDataHighwayMapper.insert(passDataHighway);
        if (passDataHighwayPicList != null && passDataHighwayPicList.size() > 0) {
            for (PassDataHighwayPic entity : passDataHighwayPicList) {
                //外键设置
                entity.setPassId(passDataHighway.getId());
                passDataHighwayPicMapper.insert(entity);
            }
        }
    }

    //超载表其他列赋值
    private DataOverloadHighway overloadAssignment(PassDataHighway passDataHighway) {
        DataOverloadHighway overload = new DataOverloadHighway();
        BeanUtils.copyProperties(passDataHighway, overload);
        //重量  限重
        Double weight = passDataHighway.getTotal();
        Double weightLimit = passDataHighway.getWeightLimit();
        //超载状态  默认超载 overloadState
        overload.setOverloadState("超载");
        //超载数
        overload.setOverloadNum(weight - weightLimit);
        //超载率
        overload.setOverloadRate((weight - weightLimit) / weightLimit * 100);
        //是否结束 初检超载为 未结束，复检完毕或手动处理后为 结束
        if ("0101".equals(passDataHighway.getCheckType())) {
            overload.setOvere(0);
        }
        if ("0202".equals(passDataHighway.getCheckType())) {
            overload.setOvere(1);
        }
        return overload;
    }

    @Override
    @Transactional
    public void updateMain(PassDataHighway passDataHighway, List<PassDataHighwayPic> passDataHighwayPicList) {
        passDataHighwayMapper.updateById(passDataHighway);

        //1.先删除子表数据
        passDataHighwayPicMapper.deleteByMainId(passDataHighway.getId());

        //2.子表数据重新插入
        if (passDataHighwayPicList != null && passDataHighwayPicList.size() > 0) {
            for (PassDataHighwayPic entity : passDataHighwayPicList) {
                //外键设置
                entity.setPassId(passDataHighway.getId());
                passDataHighwayPicMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional
    public void delMain(String id) {
        passDataHighwayPicMapper.deleteByMainId(id);
        passDataHighwayMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            passDataHighwayPicMapper.deleteByMainId(id.toString());
            passDataHighwayMapper.deleteById(id);
        }
    }

    //根据车牌号查限定时间内的超载数据
    List<DataOverloadHighway> getOverloadDate(String vehicleNo) {
        QueryWrapper<DataOverloadHighway> wrapper = new QueryWrapper<>();
        //车牌号
        wrapper.eq("vehicle_no", vehicleNo);
        //检测时间大于 当前时间 - 限定时间
        long time = DateUtils.getDate().getTime();
        long before = Long.valueOf(SpringContextUtils.getApplicationContext().getEnvironment().getProperty("config.check_type_time"));
        wrapper.ge("check_time", DateUtils.getDate(time - before));
        List<DataOverloadHighway> passDataOverloads = dataOverloadHighwayMapper.selectList(wrapper);
        //返回多条数据，因可有多条复检记录
        return passDataOverloads;
    }


    //车辆表相关业务逻辑操作
    private void vehicleOperating(PassDataHighway passDataHighway) throws Exception {
        Map<String, BaseCar> carInfo = baseCarService.getAllCar();
        //获取本车限重
        double weightLimit = 0.0;
        if (!carInfo.containsKey(passDataHighway.getVehicleNo())) {
            //车牌数据中不包含本次上报的车牌信息
            //1.看是否 超载，超载则不进行记录，不超载则进行记录
            //先根据轴型获取限重，轴型没有根据周数
            List<BaseCarWeightLimit> axleTypeList = baseCarWeightLimitMapper.selectList(null);
            Map<String, BaseCarWeightLimit> axle = new HashMap<>(16);
            axleTypeList.forEach(vo -> axle.put(vo.getModelCode(), vo));
            //轴型不为空并且该轴型在轴型表中存在
            if (!StringUtils.isEmpty(passDataHighway.getModelCode()) && axle.containsKey(passDataHighway.getModelCode())) {
                weightLimit = axle.get(passDataHighway.getModelCode()).getWeightLimit();
            } else {
                //车型为空用拿轴数默认值
                for (BaseCarWeightLimit vo : axleTypeList) {
                    if (passDataHighway.getAxesNum().equals(vo.getAxesNum()) && vo.getAcquiesceIn() == 1) {
                        weightLimit = vo.getWeightLimit();
                    }
                }
            }

            //载重不超过限重的百分之5, 此数值暂时写死后期从检测点中取，则车辆表新增数据
            if (weightLimit > passDataHighway.getTotal()) {
                //如不超载则再车辆表新增数据
                BaseCar car = new BaseCar();
                car.setVehicleNo(passDataHighway.getVehicleNo());
                car.setLicensePlateColor(passDataHighway.getLicensePlateColor());
                car.setAxesNum(passDataHighway.getAxesNum());
                car.setModelCode(passDataHighway.getModelCode());
                baseCarMapper.insert(car);
                redisTemplate.delete("getAllCarInfo");
            }


        } else {

            // 车牌数据中包含本次上报的车牌信息
            BaseCar car = carInfo.get(passDataHighway.getVehicleNo());
            //判断轴数，车型 是否相同，不相同则更新车辆表
            boolean flag1 = !car.getAxesNum().equals(passDataHighway.getAxesNum());
            boolean flag2 = !StringUtils.isEmpty(passDataHighway.getModelCode()) && StringUtils.isEmpty(car.getModelCode());
            boolean flag3 = !StringUtils.isEmpty(passDataHighway.getModelCode()) && !StringUtils.isEmpty(car.getModelCode()) && !passDataHighway.getModelCode().equals(StringUtils.isEmpty(car.getModelCode()));
            //车辆未锁定状态方可修改
            if ((flag1 || flag2 || flag3) && car.getLocking() != 1) {
                //符合条件则车辆表数据更新
                car.setAxesNum(passDataHighway.getAxesNum());
                if (flag2 || flag3) {
                    car.setModelCode(passDataHighway.getModelCode());
                }
                baseCarService.updateById(car);
                redisTemplate.delete("getAllCarInfo");
                //更新完数据后重新获取车辆及限重信息
                carInfo.clear();
                carInfo = baseCarService.getAllCar();
                weightLimit = carInfo.get(passDataHighway.getVehicleNo()).getWeightLimit();
            } else {
                weightLimit = car.getWeightLimit();
            }
        }
        passDataHighway.setWeightLimit(weightLimit);
    }

    @Override
    public List<PassDataHighwayPage> getAllOldData(Integer start, Integer size) {
        return passDataHighwayMapper.getAllOldData(start, size);
    }
}
